package Prova::Controller::Exporter;

use strict;
use warnings;
use base 'Catalyst::Controller';
use File::Temp qw(tempdir);
use Prova::Exporter;
use Prova::Archiver;
use Prova::FileMgr;
use Data::Dumper;

=head1 NAME

Prova::Controller::Exporter - Catalyst Controller

=head1 DESCRIPTION

Catalyst Controller.

=head1 METHODS

=cut

my @exported_models = qw/testcases datablocks datasections pre_operations assertions post_operations accessors testcases_tags/;

=head2 default

default action

=cut

sub default : Private {
    my ( $self, $c ) = @_;

    $c->stash->{plugins} = [ Prova::Exporter::get_plugins ];
    $c->stash->{template} = 'exporter/index.tt';
}

=head2 dl

download action

=cut

sub dl : Local {
    my ( $self, $c ) = @_;

    my $type = $c->req->args->[0];
    my $tags = $c->req->param('tags');
    if ( my ( $plugin ) = grep { $type eq $_->type } Prova::Exporter::get_plugins ) {
        $c->forward( 'fetch_data', [$tags] );
        my $workdir = $c->forward( 'make_workdir' );
         $plugin->output( $c, $workdir );
         my $archive = Prova::Archiver->archive( $c, $workdir );
         $c->log->info("archive : ".$archive);

         my $content = Prova::FileMgr->get( $archive );
         $c->response->header(
                              'Content-Type' => 'application/octet-stream',
                              '-charset' => 'Shift_JIS',
                              'Content-Disposition' => 'attachment; filename=export.zip'
                          );
         $c->response->body( $content );
    } else {
        $c->detach( '/pagenotfound/publish' ) if $type ne 'testbase';
    }
}

=head2 make_workdir

making work directory action

=cut

sub make_workdir : Private {
    my ( $self, $c ) = @_;

    my $workdir  = tempdir( CLEANUP => 1 );
    $c->log->info( "workdir : $workdir" );

    return $workdir;
}

=head2 fetch_data

fetching data action

=cut

sub fetch_data : Private {
    my ( $self, $c, $tags ) = @_;

    for my $modelname ( @exported_models ) {
        my $fetch_action = '_fetch_' . $modelname;
        my $data = $c->forward( $fetch_action, [$tags] );
        $c->forward( 'set_data', [ $modelname, $data ] );
    }
}

=head2 _fetch_testcases

=cut

sub _fetch_testcases  : Private {
    my ( $self, $c, $tags ) = @_;

    my %where;
    if ( $tags ) {
        my @tags = split ',', $tags;
        my $tags_obj = $c->forward( '/tags/get_tags', [\@tags] );
        my @tag_ids = map { $_->id } @$tags_obj if ref $tags_obj eq 'ARRAY';
        my $rels = $c->forward( '/tagmgr/get_tag_rels', [ \@tag_ids ] );
        my @testcase_ids = map { $_->test_case_id->id } @$rels if ref $rels eq 'ARRAY';
        $where{id} = @testcase_ids ? \@testcase_ids : 0;
    }

    $where{is_recording} = 0;
    my @testcases = $c->model( 'DBIC::TestCase' )->search(
                                                          \%where, { order_by => 'order_by' }
                                                      );
    my %data;
    if ( @testcases ) {
        for my $testcase ( @testcases ) {
            $data{$testcase->id} = $testcase;
        }
    }
    return \%data;
}

=head2 _fetch_datablocks

=cut

sub _fetch_datablocks : Private {
    my ( $self, $c ) = @_;

    my %data;
    my @datablocks = $c->model('DBIC::DataBlock')->search(
                                                          {},
                                                          { order_by => 'order_by' }
                                                      );
    if ( @datablocks ) {
        for my $datablock ( @datablocks ) {
            push @{$data{$datablock->test_case_id->id}}, $datablock;
        }
    }
    return \%data;
}

=head2 _fetch_datasections

=cut

sub _fetch_datasections : Private {
    my ( $self, $c ) = @_;

    my %data;
    my @datasections = $c->model('DBIC::DataSection')->search(
                                                              {},
                                                              {}
                                                          );
    if ( @datasections ) {
        for my $datasection ( @datasections ) {
            push @{$data{$datasection->data_block_id->id}}, $datasection;
        }
    }
    return \%data;
}

=head2 _fetch_pre_operations

=cut

sub _fetch_pre_operations : Private {
    my ( $self, $c ) = @_;

    my %data;
    my @pre_operations = $c->model('DBIC::PreOperation')->search(
                                                          {},
                                                          {}
                                                      );
    if ( @pre_operations ) {
        for my $pre_operation ( @pre_operations ) {
            push @{$data{$pre_operation->data_block_id->id}}, $pre_operation;
        }
        $c->log->info("pre_operation => ", Dumper \%data);
    }
    return \%data;
}

=head2 _fetch_assertions

=cut

sub _fetch_assertions : Private {
    my ( $self, $c ) = @_;

    my %data;
    my @assertions = $c->model('DBIC::Assertion')->search(
                                                          {},
                                                          {}
                                                      );
    if ( @assertions ) {
        for my $assertion ( @assertions ) {
            push @{$data{$assertion->data_block_id->id}}, $assertion;
        }
    }
    return \%data;
}

=head2 _fetch_post_operations

=cut

sub _fetch_post_operations : Private {
    my ( $self, $c ) = @_;

    my %data;
    my @post_operations = $c->model('DBIC::PostOperation')->search(
                                                          {},
                                                          {}
                                                      );
    if ( @post_operations ) {
        for my $post_operation ( @post_operations ) {
            push @{$data{$post_operation->data_block_id->id}}, $post_operation;
        }
        $c->log->info("post_operation => ", Dumper \%data);
    }
    return \%data;
}

=head2 _fetch_accessors

=cut

sub _fetch_accessors : Private {
    my ( $self, $c ) = @_;

    my %data;
    my @accessors = $c->model('DBIC::Accessor')->search(
                                                        {},
                                                        {}
                                                    );
    if ( @accessors ) {
        for my $accessor ( @accessors ) {
            push @{$data{$accessor->data_block_id->id}}, $accessor;
        }
    }
    return \%data;
}

=head2 _fetch_testcases_tags

=cut

sub _fetch_testcases_tags : Private {
    my ( $self, $c ) = @_;

    my @data = $c->model('DBIC::TestcasesTags')->search(
                                                        {},
                                                        {}
                                                    );

    return \@data;
}

=head2 set_data

=cut

sub set_data : Private {
    my ( $self, $c, $modelname, $data ) = @_;

    $c->stash->{expoted_data}->{$modelname} = $data;
}

=head2 get_data

=cut

sub get_data {
    my ( $self, $c, $modelname ) = @_;

    return $c->stash->{expoted_data}->{$modelname};
}

=head2 get_all_data

=cut

sub get_all_data {
    my ( $self, $c ) = @_;

    my %data;
    for my $modelname ( @exported_models ) {
        $data{$modelname} = $self->get_data( $c, $modelname );
    }

    return \%data;
}

=head1 AUTHOR

Shanon Inc, E<lt>http://www.shanon.co.jp/E<gt>

=head1 LICENSE

This library is free software, you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

1;
